﻿////////////////////////////////////////////////////////////////////////////////
// Datakommunikation - Laboration 1
// server.c
// 
// Filip Anic
// Marckus Asplund
// Nicklas Edmark
// Viktor Lyresten
// Tobias Savinainen
////////////////////////////////////////////////////////////////////////////////

// Disable deprecation warnings...
#define _CRT_SECURE_NO_WARNINGS

// Header files
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <simpio.h>
#include <genlib.h>
#include <strlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>

// Constants
#define DEFAULT_BUFFLEN 512
#define MAX_THREADS 5
#define NOT_FOUND 404
#define OK 200
#define NOT_MODIFIED 304
#define RET_FAILED -1
#define RET_SUCCESS 1
#define RETUR 13
#define SERVICE_ON 1
#define SERVICE_OFF 2
#define STATUS 3
#define DOWNLOAD 4
#define END 5

// Structs
typedef struct{
    string portNumber;
    string filePath;
    string logPath;
    string telnetPort;
    string telnetPassword;
} configT;

typedef struct{
	string userIP;
	char timeStr[80];
	char GMT[10];
	char cmdHTTP[80]; //Get / Conditional GET
	char filenameHTTP[80];
	char protocolHTTP[80];
	int httpAnswer; //OK, Not modified, Error
	int bitsDownloaded;
}*userInfoT;

// Global variables
bool serverOnlineOrNot;

// Function prototypes
int initWinsock();
void cleanWinsock();
int readConfigFile(configT* config);
SOCKET createServer(string portNumber);
SOCKET createClient(SOCKET serverSocket);
DWORD WINAPI clientThread(LPVOID threadData);
DWORD WINAPI handleTelnetThread(LPVOID threadData);
int sendFile(char *fileRequest, SOCKET clientSocket, string header);
void checkGet(char *httpReq, userInfoT userInfo, configT configFile);
int checkFileTime(char *filename, char *modTimeSince);
int saveUserInfo(userInfoT userInfo, string userFile);
bool serverStatus();
int readConfigFile(configT *configFile);
string contentType(string mime);
int checkFileExist(userInfoT userInfo, configT configFile);
string createHeader(userInfoT userInfo, string mimeType);
int monthToMonth(char *month);
int getTime(userInfoT userInfo);
int recvMessageTelnet(SOCKET clientSocket, char *incMessage);
int telnetRequest(string request);
int handleRequests(int request, SOCKET clientSocket, string logFile);
string getIpAddress();

// Entry point of application
int main(){
	SOCKET serverSocket = INVALID_SOCKET;
    SOCKET clientSocket = INVALID_SOCKET;
    SOCKET telnetSocket = INVALID_SOCKET;
    configT config;
    DWORD threadID;
    HANDLE telnetThread;

    // Initialize winsock
    if(initWinsock() == RET_FAILED)
    {
        cleanWinsock();
        return RET_FAILED;
    }

    serverOnlineOrNot = TRUE;

    // Load the configuration file
    if(readConfigFile(&config) == RET_FAILED)
    {
        cleanWinsock();
        return RET_FAILED;
    }

    // Create the server and make sure it's valid
    serverSocket = createServer(config.portNumber);
    if(serverSocket == INVALID_SOCKET)
    {
        cleanWinsock();
        return RET_FAILED;
    }

    // Create telnet server
    telnetSocket = createServer(config.telnetPort);
	telnetThread = CreateThread(NULL, 0, handleTelnetThread, (void *)telnetSocket, 0, NULL);
	if(telnetThread == NULL){
		printf("Failed in creating telnetThread\n");
	}

    // Start the webserver
    while(TRUE)
    {
        // Check server status
        if(!serverStatus())
        {
            closesocket(serverSocket);
			serverSocket = INVALID_SOCKET;
            continue;
        }

        // Always make sure the server is valid
        if(serverSocket == INVALID_SOCKET)
			serverSocket = createServer(config.portNumber);

        // Wait for a client to connect...
        clientSocket = createClient(serverSocket);
        if(clientSocket == INVALID_SOCKET)
        {
            printf("socket failed with error %d\n", WSAGetLastError());
			closesocket(clientSocket);
        }
        else 
        {
            CreateThread(NULL, 0, clientThread, (LPVOID)clientSocket, 0, &threadID);
        }
    }

    closesocket(serverSocket);
    cleanWinsock();
    return RET_SUCCESS;
}

/* Function: initWinsock()
 * This function initializes winsock.
 * Returns: RET_FAILED if something went wrong, otherwise RET_SUCCESS
 */
int initWinsock()
{
	WSADATA wsaData;
	if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        printf("WSAStartup failed!\n");
        getchar();
        return RET_FAILED;
	}

	return RET_SUCCESS;
}

/* Function: cleanWinsock()
 * This function cleans up winsock and wait for user input
 */
void cleanWinsock()
{
    WSACleanup();
    printf("Press any key to quit...\n");
    getchar();
}

/* Function: createServer(portNumber)
 * This function creates a server socket that listens to a user specified
 * port number.
 * Returns: INVALID_SOCKET if something went wrong, otherwise the server
 */
SOCKET createServer(string portNumber)
{
    int result;
	SOCKET serverSocket;
	struct addrinfo *info;

    // Create the server socket and make sure it's valid
	serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(serverSocket == INVALID_SOCKET)
    {
		printf("socket() failed with error %d\n", WSAGetLastError());
		closesocket(serverSocket);
		return INVALID_SOCKET;
	}

    // Get the ip-adress
	if(getaddrinfo("localhost", portNumber, NULL, &info) != 0)
    {
		printf("getaddrinfo() failed with an error %d\n", WSAGetLastError());
        closesocket(serverSocket);
		return INVALID_SOCKET;
	}
    
    while(info->ai_family != AF_INET && info->ai_next != NULL)
	    info = info->ai_next;

    // Bind the server to the adress
	result = bind(serverSocket, info->ai_addr, info->ai_addrlen);
	if(result != 0)
    {
		printf("bind() failed with error %d\n", WSAGetLastError());
		closesocket(serverSocket);
		return INVALID_SOCKET;
	}

    // Start to listen
	if(listen(serverSocket, SOMAXCONN) == SOCKET_ERROR)
    {
		printf("listen() failed with an error %d\n", WSAGetLastError());
		closesocket(serverSocket);
		return INVALID_SOCKET;
	}

	printf("Listening socket is listening...\n");
	return serverSocket;
}

/* Function: createClient(serverSocket)
 * This function create and waits for a client trying to connect to a 
 * user specified server socket.
 * Returns: INVALID_SOCKET if something went wrong, otherwise the client socket
 */
SOCKET createClient(SOCKET serverSocket)
{
    SOCKET clientSocket = INVALID_SOCKET;
    struct sockaddr clientAddr;
    int clientAddrLen;
    int result;
    char hostName[100];
    char portNumber[100];

    // Wait for a client to connect
    clientAddrLen = sizeof(clientAddr);
    clientSocket  = accept(serverSocket, &clientAddr, &clientAddrLen);        

    // Make sure the connected client is valid
    if(clientSocket == INVALID_SOCKET)
    {
        printf("accept() failed: %d\n", WSAGetLastError());
        return INVALID_SOCKET;
    }

    // Get the name of the client 
    result = getnameinfo(&clientAddr, clientAddrLen, hostName, 100, portNumber, 100, NI_NUMERICSERV);
    if(result != 0)
    {
        printf("getnameinfo() failed %d\n", WSAGetLastError());
        closesocket(clientSocket);
        return INVALID_SOCKET;
    }

    printf("Client connected: %s on port number %s.\n", hostName, portNumber);
    return clientSocket;
}

/* Function: serverStatus()
 * This function checks the current status of the server
 * Return: ON or OFF
 */
bool serverStatus(){
	return serverOnlineOrNot;
}

/* Function: readConfigFile(configFile)
 * This function reads the data from a config file
 * Returns: RET_FAILED if something went wrong, otherwise RET_SUCCESS
 */
int readConfigFile(configT *configFile){
    FILE* fp;

    if((fp = fopen("config.txt", "r")) == NULL){
            printf("Couldn't open config.txt\n");
            return RET_FAILED;
    }

    configFile->portNumber     = ReadLine(fp);
	configFile->telnetPort     = ReadLine(fp);
    configFile->filePath       = ReadLine(fp);
    configFile->telnetPassword = ReadLine(fp);
	configFile->logPath        = ReadLine(fp);
    
    fclose(fp);

    return RET_SUCCESS;
}

/* Function: sendFile(fileRequestm, clientSocket, header)
 * This function send a file to a client socket.
 * Return: The amount of data sent or RET_FAILED if something went wrong
 */
int sendFile(char *fileRequest, SOCKET clientSocket, string header){

	FILE *sendFile;
	int iSendResult, freadResult, totalSentBits = 0;
	char sendBuff[DEFAULT_BUFFLEN];

	iSendResult = send(clientSocket, header, strlen(header), 0);

    // Open the requested file
	sendFile = fopen(fileRequest,"rb");
	if(sendFile == NULL){
		printf("Error, cant open file: %s\n", fileRequest);
		return RET_FAILED;
	}

	// Start to read and send data from the requested file
	while(!feof(sendFile)){
		freadResult = fread(sendBuff, sizeof(char), DEFAULT_BUFFLEN, sendFile);
		iSendResult = send(clientSocket, sendBuff, freadResult, 0);
        if (iSendResult == SOCKET_ERROR) {
            printf("send failed: %d\n", WSAGetLastError());
            return totalSentBits;
        }

		totalSentBits += iSendResult;
	}

	fclose(sendFile);
	return totalSentBits;
}



/* Function: checkFileTime(filename, modTimeSince)
 * This functions checks the file time
 * Returns: The status code (OK, NOT_MODIFIED, NOT_FOUND)
 */
int checkFileTime(char *filename, char *modTimeSince){
	struct stat buf;
	struct tm timeSince;
	char timeStr[ 100 ] = "";
	time_t sinceTime;
	double result;
	char year[10], mon[10], day[10], hour[10], min[10], sec[10], buffer[10];

	sscanf(modTimeSince,"%s %s %s %s %2s%*c%2s%*c%2s", buffer, day, mon, year, hour, min, sec);
	timeSince.tm_year = atoi(year)-1900;
	timeSince.tm_mon = monthToMonth(mon);
	timeSince.tm_mday = atoi(day);
	timeSince.tm_hour = atoi(hour);
	timeSince.tm_min = atoi(min);
	timeSince.tm_sec = atoi(sec);

	if((sinceTime = mktime(&timeSince)) != (time_t)-1){
		/*asctime_s( buff, sizeof(buff), &timeSince);
		printf( "In days the time wilsddafgdsfgl be %s\n", buff );*/
	}else
		return OK; 

	if (!stat(filename, &buf)){
		/*strftime(timeStr, 100, "%d %b %Y %H:%M:%S", localtime( &buf.st_mtime));
		printf("\nLast modified date and time = %s\n", timeStr);*/
	}else{
		return NOT_FOUND;
	}
	result = difftime(buf.st_mtime, sinceTime);
	//printf("Resultat: %f\n", result);
	if(result < 0)
		return NOT_MODIFIED;
	else
		return OK;
}

/* Function: checkGet(httpReq, userInfo, configFile)
 * This function gets the time from the If-Modified-since-header and saves it
 */
void checkGet(char *httpReq, userInfoT userInfo, configT configFile){
    char cmdHTTP[150];
	char filenameHTTP[150];
	char protocolHTTP[150];
	int ok = sscanf(httpReq,"%s %s %s",cmdHTTP,filenameHTTP,protocolHTTP);
	char *next = strstr(httpReq,"\n");
	while(next) {
		char name[500];
		char value[500];
		int ok = sscanf(next+1,"%s",name);
		char *space = strstr(next+1," ");
		next = strstr(next+1,"\n");
		if(space) {
		    memcpy(value,space+1,next-space-1);
		    value[next-space-1]=0;
		}
		if(ok==1) {
			if(strcmp(name,"If-Modified-Since:")==0) {
				if(strcmp(cmdHTTP,"GET")==0) {
					printf("I got a conditional GET with the date: %s\n",value);
					userInfo->httpAnswer = checkFileTime(Concat(configFile.filePath,userInfo->filenameHTTP),value);
					userInfo->bitsDownloaded = 0;
				}
			}
		}
	}
}

/* Function: clientThread(threadData)
 * This function process the client 
 * Returns: RET_FAILED if something went wrong, otherwise 0
 */
DWORD WINAPI clientThread(LPVOID threadData){
	SOCKET clientSocket = (SOCKET)threadData;
	userInfoT userInfo;
	configT configFile;
	int iResult;
	string indexHTML, header;
	char recvBuff[1024];
	string sendMime;
	userInfo = New(userInfoT);
	
	if(readConfigFile(&configFile) < 0){
		printf("Reading file failed\n");
		return RET_FAILED;
	}

    userInfo->userIP = getIpAddress();

	// Receive data from the client
	iResult = recv(clientSocket, recvBuff, 512, 0);
	if(iResult > 0){
	}else{
		printf("Recv failed with an error: %d\n", WSAGetLastError());
		printf("Closing socket...\n");
		closesocket(clientSocket);
		return RET_FAILED;
	}

    // Print the data to the console
	recvBuff[iResult] = '\0'; 
	printf("%s\n", recvBuff);

	userInfo->httpAnswer = OK; 

    // Set log info
	sscanf(recvBuff,"%s %s %s\n",userInfo->cmdHTTP, userInfo->filenameHTTP, userInfo->protocolHTTP);
	if(strcmp(userInfo->filenameHTTP, "/") == 0){
		indexHTML = "\\index.html";
		sscanf(indexHTML, "%s", userInfo->filenameHTTP);
	}else{
		userInfo->filenameHTTP[0] = '\\';
	}

	// Check if the file exist
	iResult = checkFileExist(userInfo,configFile);
	if(iResult < 0)
		userInfo->httpAnswer = NOT_FOUND;
    else{
		sendMime = contentType(userInfo->filenameHTTP);
		checkGet(recvBuff, userInfo, configFile);
	}

    // Get the time
	iResult = getTime(userInfo);
	if(iResult > 0)
		printf("Successfully updated current time\n");

	header = createHeader(userInfo, sendMime);

	// If the file exist then send it to the client
	if(userInfo->httpAnswer == OK){
		userInfo->bitsDownloaded = sendFile(Concat(configFile.filePath,userInfo->filenameHTTP), clientSocket, header);
		if(userInfo->bitsDownloaded < 0)
			userInfo->bitsDownloaded = 0;
	}else if(userInfo->httpAnswer == NOT_FOUND){
        // Otherwise send the notfound.html to the client
		userInfo->bitsDownloaded = sendFile(Concat(configFile.filePath, "notfound.html"), clientSocket, header);
        if(userInfo->bitsDownloaded < 0)
			userInfo->bitsDownloaded = 0;
	}

    // Save to the log...
	iResult = saveUserInfo(userInfo, configFile.logPath);
	if(iResult < 0){
		printf("Failed in storing user information\n");
	}else
		printf("Successfully stored user information\n");

    // Closing down the socket
	printf("Closing socket...\n");
	iResult = shutdown(clientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(clientSocket);
        return 0;
    }

	closesocket(clientSocket);
	return 0;
}

 /* Function: handleTelnetThread(threadData)
  * This function handles the telnet thread
  * Returns: 0
  */
DWORD WINAPI handleTelnetThread(LPVOID threadData){
	SOCKET telnetSocket = (SOCKET)threadData;
	SOCKET clientSocket;
	configT configFile;
	int iResult, passSize;
	bool closeConnection = TRUE;

	char incMessage[100] = "";
	string sendMessage, sendPassMessage;

	readConfigFile(&configFile);

	while(TRUE){

		clientSocket = accept(telnetSocket, NULL, NULL);

		if(clientSocket == INVALID_SOCKET){
			printf("Socket invalid\n");
			closesocket(clientSocket);
			return 0;
		}

		printf("A client has connected\n");
		// Send intro message
		sendMessage = "Hello, welcome to the servers telnet administration\r\n";
		send(clientSocket, sendMessage, strlen(sendMessage), 0);
		sendPassMessage = "Please enter password:\r\n";
		send(clientSocket, sendPassMessage, strlen(sendPassMessage), 0);

		// Check password
		passSize = strlen(configFile.telnetPassword);
		while(1){
			iResult = recvMessageTelnet(clientSocket, incMessage);
			if(StringEqual(incMessage, configFile.telnetPassword) 
				|| StringEqual(SubString(incMessage, 1, passSize), configFile.telnetPassword))
				break;
		}
		sendPassMessage = "Welcome!\r\n";
		send(clientSocket, sendPassMessage, strlen(sendPassMessage), 0);
	
		while(closeConnection){
			sendMessage = "What would you like to do?\r\n";
			send(clientSocket, sendMessage, strlen(sendMessage), 0);
			sendMessage = "SERVICE ON, SERVICE OFF\r\nSTATUS\r\nDOWNLOAD\r\nEND\r\n\r\n";
			send(clientSocket, sendMessage, strlen(sendMessage), 0);

			recvMessageTelnet(clientSocket, incMessage);
			iResult = telnetRequest(incMessage);
			closeConnection = handleRequests(iResult, clientSocket, configFile.logPath);

		}
		closesocket(clientSocket);
		clientSocket = INVALID_SOCKET;
		printf("The client has disconnected\n");
		closeConnection = TRUE;
	}
	return 0;
}

/* Function: handleRequests(request, clientSocket, logFile)
 * This function handles telnet-requests
 * Return: TRUE or FALSE
 */
int handleRequests(int request, SOCKET clientSocket, string logFile){
	string message;

	if(request == RET_FAILED)
		return TRUE;
	else if(request == SERVICE_ON){
		printf("Server is on\n\n");
		serverOnlineOrNot = TRUE;
		return TRUE;
	}
	else if(request == SERVICE_OFF){
		printf("Server is closing\n\n");
		serverOnlineOrNot = FALSE;
		return TRUE;
	}
	else if(request == STATUS){
		if(serverOnlineOrNot == TRUE){
			message = "Server is running\r\n\n";
			send(clientSocket, message, strlen(message), 0);
		}else{
			message = "Server is down\r\n\n";
			send(clientSocket, message, strlen(message), 0);
		}
		return TRUE;
	}
	else if(request == DOWNLOAD){
		char sendBuff[DEFAULT_BUFFLEN];
		FILE *fp;
		int i;
		if((fp = fopen(logFile, "r")) == NULL){
			message = "Failed to open log file\r\n";
			send(clientSocket, message, strlen(message), 0);
			return TRUE;
		}

		while(fp != EOF){
			if(fgets(sendBuff,DEFAULT_BUFFLEN,fp) == NULL)
				break;
			i = strlen(sendBuff);
			sendBuff[i] = '\r';
			sendBuff[i+1] = '\n';
			i++;
			send(clientSocket,sendBuff,i,0);
		}
		fclose(fp);
		return TRUE;
	}
	else if(request == END){
		closesocket(clientSocket);
		return FALSE;
	}
	else
		return TRUE;

}

/* Function: telnetRequest(request)
 * This function parses the telnet-request
 * Returns: SERVICE_ON, SERVICE_OFF,STATUS, DOWNLOAD, END or RET_FAILED
 */
int telnetRequest(string request) {
	
	if(StringEqual(ConvertToUpperCase(request), "SERVICE ON") 
			|| StringEqual(SubString(ConvertToUpperCase(request), 1, strlen("SERVICE ON")), "SERVICE ON"))
			return SERVICE_ON;
	else if(StringEqual(ConvertToUpperCase(request), "SERVICE OFF") 
			|| StringEqual(SubString(ConvertToUpperCase(request), 1, strlen("SERVICE OFF")), "SERVICE OFF"))
			return SERVICE_OFF;
	else if(StringEqual(ConvertToUpperCase(request), "STATUS") 
			|| StringEqual(SubString(ConvertToUpperCase(request), 1, strlen("STATUS")), "STATUS"))
			return STATUS;
	else if(StringEqual(ConvertToUpperCase(request), "DOWNLOAD") 
			|| StringEqual(SubString(ConvertToUpperCase(request), 1, strlen("DOWNLOAD")), "DOWNLOAD"))
			return DOWNLOAD;
	else if(StringEqual(ConvertToUpperCase(request), "END") 
			|| StringEqual(SubString(ConvertToUpperCase(request), 1, strlen("END")), "END"))
			return END;
	else
		return RET_FAILED;

}

/* Function: telnetRequest(request)
 * This function parses the telnet-request
 * Returns: SERVICE_ON, SERVICE_OFF,STATUS, DOWNLOAD, END or RET_FAILED
 */
int recvMessageTelnet(SOCKET clientSocket, char *incMessage){

	int i = 0, rSize = 0;
	char ch;

	while (rSize += recv(clientSocket, &ch, 1, 0)) { 
		if (ch == (char)RETUR)
			break;

		incMessage[i] = ch;					
		send(clientSocket, (char*)ch, 1, 0);	
		i++;
	}

	incMessage[i+1] = '\0';

	return rSize;
}

/* Function: createHeader(userInfo, mimeType)
 * This function creates the http-header information
 * Returns: The header
 */
string createHeader(userInfoT userInfo, string mimeType){
	time_t bTime;
	string header, buffer;
	char timeNow[80];
	buffer = IntegerToString(userInfo->httpAnswer);
	header = "";
	header = Concat(header,userInfo->protocolHTTP);
	header = Concat(header, " ");
	header = Concat(header, buffer);
	header = Concat(header, " ");
	time(&bTime);

	if(userInfo->httpAnswer == 404){
		header = Concat(header,"Not Found");
		return header;
	}
	else if(userInfo->httpAnswer == 304){
		header = Concat(header, "Not Modified");
		return header;
	}
	
	strftime(timeNow, 80, "%a %d %b %Y %H:%M:%S", localtime(&bTime));
	printf("\n\n\n%s\n\n\n",timeNow);

	header = Concat(header," 200 OK");
	header = Concat(header, "\r\nContent-type: ");
	header = Concat(header, mimeType);
	header = Concat(header, "\r\nCache-Control: max-age=21600");
	header = Concat(header, "\r\nLast-Modified: ");
	header = Concat(header, timeNow);
	header = Concat(header, "\r\n\r\n");
	return header;
}

/* Function: saveUserInfo(userInfo, userFile)
 * This function saves the user information to the log
 * Returns: RET_FAILED or 1
 */
int saveUserInfo(userInfoT userInfo, string userFile) {
	
	FILE *fp;
	string info, temp;
	fp = fopen(userFile,"a");
	if(fp == NULL){
		printf("Error in opening logfil\n");
		return RET_FAILED;
	}

	info = Concat(userInfo->userIP, " ");
	info = Concat(info, Concat(userInfo->timeStr, "\n\""));
	info = Concat(info, Concat(userInfo->cmdHTTP, " "));
	info = Concat(info, Concat(userInfo->filenameHTTP, " "));
	info = Concat(info, Concat(userInfo->protocolHTTP,"\" "));
	temp = IntegerToString(userInfo->httpAnswer);
	info = Concat(info, Concat(temp, " "));
	temp = IntegerToString(userInfo->bitsDownloaded);
	info = Concat(info, temp);
	
	if(fputs(info,fp) != EOF);
	else{
		printf("Error in writing to the file: savefile\n");
		fclose(fp);
		return RET_FAILED;
	}
	fputs("\n-------------------------------------------------------\n",fp);

	fclose(fp);
	return 1;
}

/* Function: checkFileExist(userInfo, configFile)
 * This function check if a file exists
 * Return: RET_SUCCESS if the file exists, otherwise RET_FAILED
 */
int checkFileExist(userInfoT userInfo, configT configFile){
	FILE *fp;

	if((fp = fopen(Concat(configFile.filePath,userInfo->filenameHTTP), "r")) == NULL){
		//printf("Could't open file %s\n", userInfo->filenameHTTP);
		return RET_FAILED;
	}
	fclose(fp);
	return RET_SUCCESS;

}

/* Function: contentType(filename)
 * This function returns the correct mimetype from the file type
 * Returns: The mime type
 */
string contentType(string filename){
	string mime = SubString(filename, strlen(filename)-4, strlen(filename));

    if(strcmp(mime, ".jpg") == 0)
            return "image/jpeg";
    else if(strcmp(mime, "jpeg") == 0)
            return "image/jpeg";
    else if(strcmp(mime, "html") == 0 || strcmp(mime, ".htm") == 0)
            return "text/html";
    else if(strcmp(mime, ".png") == 0)
            return "image/png";
    else if(strcmp(mime, ".gif") == 0)
            return "image/gif";
    else if(strcmp(mime, ".zip") == 0)
            return "application/x-zip-compressed";
    else if(strcmp(mime, ".ico") == 0)
            return "image/ico";
    else return "application/octet-stream";
}

/* Function: monthToMonth(month)
 * This function converts months (in string form) to a number
 * Returns: A month (between 0-11) or -1 if the function fails
 */
int monthToMonth(char *month){
	if(strcmp(month, "Jan") == 0)
		return 0;
	else if(strcmp(month, "Feb") == 0)
		return 1;
	else if(strcmp(month, "Mar") == 0)
		return 2;
	else if(strcmp(month, "Apr") == 0)
		return 3;
	else if(strcmp(month, "May") == 0)
		return 4;
	else if(strcmp(month, "Jun") == 0)
		return 5;
	else if(strcmp(month, "Jul") == 0)
		return 6;
	else if(strcmp(month, "Aug") == 0)
		return 7;
	else if(strcmp(month, "Sep") == 0)
		return 8;
	else if(strcmp(month, "Oct") == 0)
		return 9;
	else if(strcmp(month, "Nov") == 0)
		return 10;
	else if(strcmp(month, "Dec") == 0)
		return 11;
	else
		return -1;
}

/* Function: getTime(userInfo)
 * This function saves the current time to the user info variable
 * Returns: RET_FAILED if something went wrong, otherwise RET_SUCCESS
 */
int getTime(userInfoT userInfo){

	time_t gTime, lTime, bTime;
	struct tm *gTimeS, *lTimeS;
	double result;
	string temp;
	time(&bTime);
	strftime(userInfo->timeStr, 80, "[ %d/%b/%Y:%H:%M:%S ", localtime( &bTime));

	time(&gTime);
	gTimeS = gmtime(&gTime);
	if((gTime = mktime(gTimeS)) == (time_t)-1){
		strcat(userInfo->timeStr, "-1]");
		return RET_FAILED;
	}
	
	time(&lTime);
	lTimeS = localtime(&lTime);
	if((lTime = mktime(lTimeS)) == (time_t)-1){
		strcat(userInfo->timeStr, "-1]");
		return RET_FAILED;
	}

	result = difftime(lTime,gTime);
	temp = IntegerToString((int)((result/60)/60));
	strcat(userInfo->timeStr, temp);
	strcat(userInfo->timeStr, "]");

	return RET_SUCCESS;
	
}

/* Function: getIpAddress()
 * This function returns the ipaddress of server
 * Returns: The ipaddress
 */
string getIpAddress(){
    char serverHost[100];
    struct hostent *remoteHost;

	if(gethostname(serverHost, sizeof(serverHost)) == SOCKET_ERROR){
		printf("gethostname failed with and error: %d\n", WSAGetLastError());
		return "Could not find Ip adress";
	}else{
		remoteHost=gethostbyname(serverHost);
		return inet_ntoa (*(struct in_addr *)*remoteHost->h_addr_list);
	}
}